import tensorflow_datasets as tfds
iris, iris_info=tfds.load('iris', with_info=True)
print(iris_info)
tfds.core.DatasetInfo(
name='iris',
full_name='iris/2.0.0',
description="""
This is perhaps the best known database to be found in the pattern recognition
literature. Fisher's paper is a classic in the field and is referenced
frequently to this day. (See Duda & Hart, for example.) The data set contains
3 classes of 50 instances each, where each class refers to a type of iris
plant. One class is linearly separable from the other 2; the latter are NOT
linearly separable from each other.
""",
homepage='https://archive.ics.uci.edu/ml/datasets/iris',
data_path='/Users/csian/tensorflow_datasets/iris/2.0.0',
download_size=4.44 KiB,
dataset_size=7.62 KiB,
features=FeaturesDict({
'features': Tensor(shape=(4,), dtype=tf.float32),
'label': ClassLabel(shape=(), dtype=tf.int64, num_classes=3),
}),
supervised_keys=('features', 'label'),
disable_shuffling=False,
splits={
'train': <SplitInfo num_examples=150, num_shards=1>,
},
citation="""@misc{Dua:2019 ,
author = "Dua, Dheeru and Graff, Casey",
year = "2017",
title = "{UCI} Machine Learning Repository",
url = "http://archive.ics.uci.edu/ml",
institution = "University of California, Irvine, School of Information and Computer Sciences"
}""",
)
splits를 보면 데이터가 ‘train’ 속성밖에 없다.
split datasets(train(0.7), test(0.3))_.take(), .skip()
tensorflow_datasets 라이브러리는 DatasetBuilder 객체를 통해 데이터셋을 로드하기 전에 슬라이싱과 분할을 정의할 수 있다.
혹은 .take(), .skip() 메서드를 사용해서 데이터셋을 분할 할 수 있다.
훈련샘플과 테스트 샘플이 섞이지 않다고 유의할 것!
.shuffle() 메서드의 reshuffle_each_iteration=False 매개변수를 지정
tf.random.set_seed(1)
ds_orig=iris['train']
ds_orig=ds_orig.shuffle(150, reshuffle_each_iteration=False)
ds_train_orig=ds_orig.take(100)
ds_test=ds_orig.skip(100)
ds_train_orig=ds_train_orig.map(lambda x:(x['features'], x['label']))
ds_test=ds_test.map(lambda x:(x['features'], x['label']))
map을 이용해서 딕셔너리를 튜플로 변환
tf.keras.Sequential 다층 신경망 Dense 층(tf.keras.layers.Dense)완전 연결 층 또는 선형 층이라고 불린다. f(wXx+b)
class Dense
: Just your regular densely-connected NN layer. iris_model=tf.keras.Sequential([tf.keras.layers.Dense(16, activation='sigmoid', name='fc1', input_shape=(4, )), tf.keras.layers.Dense(3, activation='softmax', name='fc2')])
iris_model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
fc1 (Dense) (None, 16) 80
_________________________________________________________________
fc2 (Dense) (None, 3) 51
=================================================================
Total params: 131
Trainable params: 131
Non-trainable params: 0
_________________________________________________________________
일반적으로 입력에 대하여 차원의 일부가 고정되어 있다. 따라서 출력 차원만 직접 고려하면 된다.
위에서 모델을 생성할 때, input_shape=(4, )으로 지정했기 때문에, 별도의 .build()를 할 필요 없다.
파라미터의 크기는 (n_in+1)x(n_out)이다.(가중치 행렬: n_in X n_out 개, 절편 벡터: n_out)
ex) fc1; n_in:4, n_out:16 -> parem#:80
iris_model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
adam(Adaptive Moment Estimation)
sparse_categorical_crossentropy: 다중 분류 손실함수
다중 분류일 경우 타깃이 원-핫 인코딩 되어 있으면 loss 매개변수를 ‘categorical_crossentropy’
타깃이 정수 값일 경우 sparse_categorical_crossentropy
num_epochs=100
training_size=100
batch_size=2
steps_per_epoch=np.ceil(training_size/batch_size)
ds_train=ds_train_orig.shuffle(buffer_size=training_size)
ds_train=ds_train.repeat()
ds_train=ds_train.batch(batch_size=batch_size)
ds_train=ds_train.prefetch(buffer_size=1000)
history=iris_model.fit(ds_train, epochs=num_epochs, steps_per_epoch=steps_per_epoch, verbose=0)
compile 메서드에서 metrics를 통해서 평가지표로 지정한 ‘accuracy’와 비용함수에 대한 ‘loss'는 history.history에 저장(dictionary)
hist=history.history
fig=plt.figure(figsize=(12, 5))
ax=fig.add_subplot(1, 2, 1)
ax.plot(hist['loss'], lw=3)
ax.set_title('Training loss', size=15)
ax.set_xlabel('Epoch', size=15)
ax.tick_params(axis='both', which='major', labelsize=15)
ax=fig.add_subplot(1, 2, 2)
ax.plot(hist['accuracy'], lw=3)
ax.set_title('Training accuracy', size=15)
ax.set_xlabel('Epoch', size=15)
ax.tick_params(axis='both', which='major', labelsize=15)
plt.show()
Evaluate trained model
iris_model.compile() 에서 평가지표로 ‘accuracy’를 지정했기 때문에 테스트 데이터셋에서 모델의 정확도를 바로 평가할 수 있다.
results=iris_model.evaluate(ds_test.batch(50), verbose=0)
print('테스트 손실: {:.4f} 테스트 정확도: {:.4f}'.format(*results))
테스트 손실: 0.1483 테스트 정확도: 0.9800
모델 입력이 적절한 차원을 가지도록 테스트 데이터셋도 배치로 입력해야 ㅎ나다.
.batch()를 호출하면 추출된 텐서의 랭크가 1 증가한다.
evaluate()에 입력할 데이터는 차원이 하나 있어야 한다.
ds_test.batch(50)은 데이터셋이 크기가 50인 하나의 배치이다.
Save Model and Load it
save( .save() )
iris_model.save('iris-classifier.h5', overwrite=True, include_optimizer=True, save_format='h5')
iris_model.save() 메서드를 호출하면, 모델 구조와 학습된 모든 파라미터(위 모델 기준 131개)를 저장한다.
신경망 구조만 저장하고 싶다면, iris_model.to_json() 메서드를 사용(모델 설정을 JSON 포맷으로 저장한다.)
iris_model.save_weights() 메서드를 통해 가중치만 저장할 수 있다.
save_format 매개변수를 HDF5 포맷인 경우 h5, 텐서플로인 경우 tf로 저장한다.
load( tf.keras.models.load_model() )
iris_model_new=tf.keras.models.load_model('iris-classifier.h5')
iris_model_new.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
fc1 (Dense) (None, 16) 80
_________________________________________________________________
fc2 (Dense) (None, 3) 51
=================================================================
Total params: 131
Trainable params: 131
Non-trainable params: 0
_________________________________________________________________
이전과 동일한 결과를 내는지 확인
results=iris_model_new.evaluate(ds_test.batch(33), verbose=0)
print('테스트 손실: {:.4f} 테스트 정확도: {:.4f}'.format(*results))
테스트 손실: 0.1483 테스트 정확도: 0.9800